var plugor_language = {};
plugor_language.name = {};
plugor_language.info = {};
plugor_language.message = {
	notempty:'{name}不允许为空！',
	error:'{name}格式不正确（要求：{info}）！',
	checking:'{name}验证中……',
	exist:'{name}已存在。',
	busy:'服务器忙……',
	fail:'验证失败……',
	different:'两次输入{name}不一致！'
};
var validator = {
	required:{//如果元素为空，则返回FALSE
		test:function(str){//是否为空
			return (str || "").replace( /^\s+|\s+$/g, "") !== "";
		},
		msg:'不允许为空！'
	},
	is_exist:{
		test:function(val,url,elem,_this){
			var idx = url.indexOf('@');
			if(idx > 0){//编辑时候验证
				if(url.substring(0,idx) == val){//编辑内容没有改变
					return true;
				}
				url = url.substring(idx+1);
			}
			$.ajax({
				type: "POST",
				url: url+"/"+val,
				dataType: "json",
				success: function(result){
					var id = elem.id;
					if(result.state == 0){
						_this.tip(elem,_this._state.right,'');
					}else if(result.state == 1){
						_this.tip(elem,_this._state.error, _this._getMessage(id, 'exist'));
					}else{
						_this.tip(elem,_this._state.error, _this._getMessage(id, 'busy'));
					}
				},
				error: function(){
					_this._tip_error(elem,_this._state.error, _this._getMessage(id, 'fail'));
				}
			});
			return 'checking';
		},
		msg:''
	},
	matches:{//如果表单元素的值与参数中对应的表单字段的值不相等，则返回FALSE;eg:matches:form_item_id
		test:function(val,form_item_id){//相等验证
			return val == $('#'+form_item_id).val();
		},
		msg:'两次输入内容不一致！'
	},
	min_length:{//如果表单元素值的字符长度少于参数中定义的数字，则返回FALSE;eg:min_length:2
		test:function(val,len){
			this.msg = '要求：最小长度'+len+"，(1汉字算2长度)！";
			return val? plugor.len(val) >=len : false;
		},
		msg:''
	},
	max_length:{//如果表单元素值的字符长度大于参数中定义的数字，则返回FALSE;eg:max_length:12
		test:function(val,len){
			this.msg = '要求：最大长度'+len+"，(1汉字算2长度)！";
			return val? plugor.len(val) <=len : false;
		},
		msg:''
	},
	exact_length:{//如果表单元素值的字符长度与参数中定义的数字不符，则返回FALSE;eg:exact_length:8
		test:function(val,len){
			this.msg = '要求：长度为'+len+"，(1汉字算2长度)！";
			return val? plugor.len(val) ==len : false;
		},
		msg:''
	},
	alpha:{//如果表单元素值中包含除字母以外的其他字符，则返回FALSE
		test:function(val){
			return /^[A-Za-z]+$/.test(val);
		},
		msg:'要求：必须为英文字母！'
	},
	integer:{//如果表单元素中包含除整数以外的字符，则返回FALSE
		test:function(val){//数字
			return /^\d+$/.test(val);
		},
		msg:'请填写正整数！'
	},
	decimal:{
		test:function(val){//小数
			return /^\d+([\.]?\d{1,2})?$/.test(val);
		},
		msg:'请填写正整数或小数（精确2位）！'		
	},
	code:{
		test:function(str){
			return /^[A-Za-z0-9]+$/.test(str);
		},
		msg:'请填写数字或者字母！'
	},
	username:{
		test:function(str){//用户名4-16位字母、数字和下划线（_）组成，（必须以字母开头）。
			return /^[A-Za-z]\w{3,15}$/.test(str);
		},
		msg:'4-16位字母、数字和下划线（_）组成，（必须以字母开头）！'
	},
	password:{
		test:function(str){//密码长度6～16位，字母区分大小写。
			return /\S{6,16}/.test(str);
		},
		msg:'密码长度6～16位，字母区分大小写！'
	},
	realname:{
		test:function(str){
			return /^([\u4e00-\u9fa5]{2,12})|([a-zA-Z0-9]{3,20})$/.test(str);
		},
		msg:'汉字(2~12)或字母(3-20)组成！'
	},
	email:{
		test:function(str){
			return /^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}\.){1,4}[a-z]{2,4}$/.test(str);
		},
		msg:'格式输入错误！'
	},
	mobile:{
		test:function(str){//手机号码
			return /^1(3\d{1}|5[389])\d{8}$/.test(str);
		},
		msg:'格式输入错误！'
	},
	phone:{
		test:function(str){//
			return /^(\+)?([0-9]{1,3}[-\s])?([0-9]{3,4}[-\s])?([0-9]{7,8})([-\s][0-9]{1,5})?$/.test(str);
		},
		msg:'格式输入错误！'
	},
	address:{
		test:function(str){//
			return /(^[\u4e00-\u9fa5]*[0-9a-zA-Z]*([\u4e00-\u9fa5]|[0-9a-zA-Z])*$)/.test(str);
		},
		msg:'格式输入错误：不能有特殊字符！'
	},
	postcode:{
		test:function(str){
			return /^[0-9]{6}$/.test(str);
		},
		msg:'请输入正确的邮编！'
	},
	url:{
		test:function(str){
			return /^(([a-z]+:\/\/)?([\w-]+)\.([\w-]+)(\.[\w-]+)*)?(\/)?[^\s]*$/.test(str);
		},
		msg:'格式错误！eg:http://www.wocing.com'
	}
}

plugor.form = function(formId,action,items_rules){
	
	this._name = '_name';		//名字
	this._value = '_value';		//内容
	this._tip = '_tip';			//提示
	this._view = true;		//提示信息：true 显示在页面上；false 鼠标划过输入框才显示到页面。
	
	this._state = {
		def:'default',//默认
		notice:'notice',//提示
		right:'right',//正确	
		error:'error',//错误
		warning:'warning',//警告
		loading:'loading'//加载	
	};

	
	this._formId = formId;
	this._action = action;
	//eg:{id:[rule,rule],name:[rule,rule]}
	this._items_rules = this.setItems_rules(items_rules);
	this.$_form = $('#'+this._formId);
	this.tipInit();
	this.init();
}

plugor.form.prototype = {

	init:function(){
		var submit = 'ajax',redirect = null,callback = null;
		var _this=this;
		if(!this._action || this._action == 'null') 
			this._action = this.$_form[0].action;
//		else
//			this.$_form[0].action = this._action;
		plugor_language.name[this._formId]={};
		plugor_language.info[this._formId]={};
		//初始化form
		this.$_form.submit(function(){
			if(_this._onsubmit()){
				switch(submit){
					case 'ajax':
						$.post(_this._action,_this.$_form.serializeArray(),function(result){
							if(result.state == -1){//服务端验证失败！
								return;
							}
							_this._message(result.state>=0?'ok':'error',result.message);
							if(callback){
								callback(_this.$_form,result);
								return;
							}
							//alert(result.html);
							if(result.html){
								_this.$_form.replaceWith(result.html);
								return;
							}
							if(redirect){
								if(top.location)
									top.location = redirect;
								else
									window.location = redirect;
								return;
							}
							if(plugor.endsWith(_this._action,'add')){
								_this._reset(_this._formId,_this.$_form);
							}else if(plugor.endsWith(_this._action,'edit')){
								top.location.reload();
							}
						},'json');
						break;
					case 'submit':
						_this.$_form[0].action = _this._action;
						_this.$_form[0].submit();
						break;
				}
			}
			return false;
		});
		this.$_form.find("input[type='button'][ajax='true']").click(function(){
			_this.$_form.submit();
		});
		
		for(var k in this._items_rules){
			plugor_language.name[this._formId][k] = $('#'+ k +this._name).text();
			plugor_language.info[this._formId][k] = $('#'+ k +this._tip).html();
			
			this.tip($('#'+k)[0],this._state.def);
			if(this._items_rules[k] && this._items_rules[k][0] == 'required'){
				var $_name = $('#'+ k + this._name);
				if(!$_name[0])
					return;
				if($_name.parent()[0].tagName.toLowerCase() === 'label')
					$_name.parent().before('<span class="red">* </span>')
				else
					$_name.before('<span class="red">* </span>');
			}
			this.bindEvent($('#'+k)[0]);
		}
	},
	setItems_rules:function(items_rules){
		var _items_rules = {};
		if(items_rules){
			for(var item in items_rules){
				_items_rules[item] = items_rules[item].split('|');
			}
		}else{//不存在则遍历表单
//			var elements = this.$_form[0].elements;
//			for(var i=0,j=elements.length;i<j;i++){
//				e = elements[i];
//				valid = e.getAttribute('valid');
//				if(valid){
//					_items_rules[e.name] = valid.split('|');
//				}
//			}
			_items_rules = null;
		}
		return _items_rules;
	},
	bindEvent:function(elem){
		var _this = this;
		$(elem).mouseover(function(){
			
		}).focus(function(){
			_this.tip(elem,_this._state.notice);
		}).blur(function(){
			_this.validator(elem);
		});
	},
	validator:function(elem,rules){
		var id = elem.id;
		var val = $(elem).val();//
		var rules = rules?rules:this._items_rules[id];
		var rule,rule_k,rule_v,rule_i;
		var is = false;//查看是否存在验证器。
		var res = false;//验证结果(ture||false)
		var msg = 'error';//抛出信息
		if(!rules){
			this.tip(elem,this._state.def);
			return;
		}
		for(var i=0,j=rules.length;i<j;i++){
			rule = rules[i];
			rule_i = rule.indexOf(":");
			if(rule_i == -1){
				if(val === '' && rules[0] !== 'required'){
					this.tip(elem,this._state.def);
					return;
				}
				res = validator[rule].test(val);
				msg = validator[rule].msg;//错误提示信息。
			}else{
				rule_k = rule.substring(0,rule_i);
				rule_v = rule.substring(rule_i+1);
				if(rule_k == 'is_exist'){
					res = validator[rule_k].test(val,rule_v,elem,this);
				}else{
					res = validator[rule_k].test(val,rule_v);
					msg = validator[rule_k].msg;//错误提示信息。
				}
			}
			switch(res){
				case 'checking':
					this.tip(elem,this._state.loading,this._getMessage(id,'checking'));
					return;
				case true:
					continue;
				case false:
					this.tip(elem,this._state.error,this._getMessage(id,msg));
					return;
			}
		}
		this.tip(elem,this._state.right,'');
		return;
	},
	tipInit:function(){
		
		this._input_class = {
			def:'input',//默认的
			ok:'inputright',
			error:'inputred',
			focus:'inputgreen',
			loading:''
		};
		this._tip_class = {
			def:'tip_default',
			notice:'tip_notice',
			ok:'tip_ok',
			error:'tip_error',
			loading:'tip_loading'
		};
	},
	tip:function(elem,state,message){
		var _this = this;
		var id = elem.id;
		switch(state){
			case _this._state.def:
				var view = '';
				if(_this._view){
					view = plugor_language.info[_this._formId][id];
				}
				$(elem).removeClass().addClass(_this._input_class.def);
				if(id)
					$('#'+id+_this._tip).removeClass().addClass(_this._tip_class.def).html(view);
				break;
			case _this._state.notice:
				$(elem).removeClass().addClass(_this._input_class.focus);
				if(id)
					$('#'+id+_this._tip).removeClass().addClass(_this._tip_class.notice).html(plugor_language.info[_this._formId][id]);
				break;
			case _this._state.right:
				$(elem).removeClass().addClass(_this._input_class.ok);
				if(id)
					$('#'+id+_this._tip).removeClass().addClass(_this._tip_class.ok).html(message);
				break;
			case _this._state.error:
				$(elem).removeClass().addClass(_this._input_class.error);
				if(id)
					$('#'+id+_this._tip).removeClass().addClass(_this._tip_class.error).html(message);
				break;
			case _this._state.warning:
				break;
			case _this._state.loading:
				if(id)
					$('#'+id+_this._tip).removeClass().addClass(_this._tip_class.loading).html(message);
				break;
		}
	},
	_getMessage:function(id,str){
		var msg = plugor_language.message[str];
		msg = msg ? msg : str;
		return msg.replace('{name}',plugor_language.name[this._formId][id])
			.replace('{info}',plugor_language.info[this._formId][id]);
	},
	_getFormData:function(){
		var data = {} ;
		this.$_form.find(":input").each(function(i,n) {
			if($(n).is(":radio")||$(n).is(":checkbox")) if(!$(n).attr("checked"))return;
			data[n.name] = $(n).val();
		}) ;
		data['random'] = Math.random();
		return data;
	},
	_onsubmit:function(){
		if(this._items_rules){
			for(var k in this._items_rules){
				this.validator($('#'+k)[0]);
			}
		}else{
			var elements = this.$_form[0].elements;
			var e,valid;
			var _items_rules = {};
			for(var i=0,j=elements.length;i<j;i++){
				e = elements[i];
				valid = e.getAttribute('valid');
				if(valid){
					this.validator(e,valid.split('|'));
				}
			}
		}
		if(this.$_form.find('.'+this._input_class.error).length > 0)
			return false;
		else
			return true;
	},
	_reset:function(){
		this.$_form[0].reset();
		this.$_form.find('div[class^="tip_"]').removeClass().addClass(this._tip_class.def);
		var info = plugor_language.info[this._formId];
		for(var name in info){
			$('#'+ name + '_tip').html(info[name]);
		}
	},
	_message:function(type,message){//submit 结果提示
		switch(type){
			case 'ok':
			case 'info':
				$.fn.mBox({message:message,fontcolor:'green'});
				break;
			case 'warning':
			case 'error':
				$.fn.mBox({message:message,fontcolor:'red'});
				break;
		}
	}
}
